package com.services.weather;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Xml;

public class YahooXmlParser {
    private static final String ns = null;
   
    public List parse(InputStream in) throws XmlPullParserException, IOException {
        try {
            XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
            parser.setInput(in, null);
            parser.nextTag();
            return readData(parser);
        } finally {
            in.close();
        }
    }

	private List readData(XmlPullParser parser) throws XmlPullParserException, IOException {
		List entries = new ArrayList();

	    parser.require(XmlPullParser.START_TAG, ns, "query");
	    while (parser.next() != XmlPullParser.END_TAG) {
	        if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
	        String name = parser.getName();
	        // Starts by looking for the entry tag
	        if (name.equals("results")) {
	            entries = readResults(parser);
	        }
	    }
	    
	    return entries;
	}
    
	private List readResults(XmlPullParser parser) throws XmlPullParserException, IOException {
		List entries = new ArrayList();

	    parser.require(XmlPullParser.START_TAG, ns, "results");
	    while (parser.next() != XmlPullParser.END_TAG) {
	        if (parser.getEventType() != XmlPullParser.START_TAG) {
	            continue;
	        }
	        String name = parser.getName();
	        // Starts by looking for the entry tag
	        if (name.equals("place")) {
	            entries.add(Place.readPlace(parser));
	        } else {
	            Place.skip(parser);
	        }
	    }  
	    return entries;
	}

	public static class Place {
		
		public final String woeid;
		
		public Place(String woeid) {
			this.woeid = woeid;
		}
		
		public static Place readPlace(XmlPullParser parser) throws XmlPullParserException, IOException {
		    parser.require(XmlPullParser.START_TAG, ns, "place");
		    String woeid = null;
		    while (parser.next() != XmlPullParser.END_TAG) {
		        if (parser.getEventType() != XmlPullParser.START_TAG) {
		            continue;
		        }
		        String name = parser.getName();
		        if (name.equals("woeid")) {
		            woeid = readWoeid(parser);
		        } else {
		            skip(parser);
		        }
		    }
		    return new Place(woeid);
		}
		
		// Processes woeid tags in the feed.
		private static String readWoeid(XmlPullParser parser) throws IOException, XmlPullParserException {
		    parser.require(XmlPullParser.START_TAG, ns, "woeid");
		    String woeid = readText(parser);
		    parser.require(XmlPullParser.END_TAG, ns, "woeid");
		    return woeid;
		}
		
		// Extract text values.
		private static String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
		    String result = "";
		    if (parser.next() == XmlPullParser.TEXT) {
		        result = parser.getText();
		        parser.nextTag();
		    }
		    return result;
		}
		
		// Skip unimportant tags
		private static void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
		    if (parser.getEventType() != XmlPullParser.START_TAG) {
		        throw new IllegalStateException();
		    }
		    int depth = 1;
		    while (depth != 0) {
		        switch (parser.next()) {
		        case XmlPullParser.END_TAG:
		            depth--;
		            break;
		        case XmlPullParser.START_TAG:
		            depth++;
		            break;
		        }
		    }
		}
	}
}
